package com.augn.utils;

import java.util.List;
import	java.util.Map;
import java.util.Map;
import java.util.Set;
import	java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * @Description:  指定缓存过期时间
     * @Param: [key 键, time单位 秒]
     * @return:布尔值
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean expire(String key,long time){
        try{
            if (time>0){
                redisTemplate.expire(key,time,TimeUnit.SECONDS);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description:  获取键的过期时间
     * @Param: [key]
    com.laiYongBin.util.RedisTempUtil
     */
    public Long getExpire(String key){
        return redisTemplate.getExpire(key,TimeUnit.SECONDS);
    }

    /**
     * @Description: 判断key是否存在
     * @Param: key:键
     * @return:布尔值
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean hasKey(String key){
        try {
            return redisTemplate.hasKey(key);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 删除一个或多个key
     * @Param: 可边长的key
    com.laiYongBin.util.RedisTempUtil
     */
    public void delete(String... key){
        if (key !=null && key.length>0 ){
            if (key.length==1){
                redisTemplate.delete(key[0]);
            }else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    /**
     * @Description: 缓存获取
     * @Param: [key]
    com.laiYongBin.util.RedisTempUtil
     */
    public Object get(String key){
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * @Description: 缓存放入
     * @Param: [key, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean set(String key, Object value){
        try{
            redisTemplate.opsForValue().set(key,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 放入缓存并设置过期时间,若是时间<=0,则是永久
            * @Param: [key, value, time]
            com.laiYongBin.util.RedisTempUtil
     */
    public boolean set(String key, Object value,long time){
        try{
            if (time>0){
                redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
            }else {
                set(key,value);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description:  递增
     * @Param: [key, delta要增加几]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean incr(String key, long delta){
        try {
            if (delta<0){
                return false;
            }
            redisTemplate.opsForValue().increment(key,delta);
            return true;
        }catch (Exception e) {
            return false;
        }
    }

    /**
     * @Description:  递减少
     * @Param: [key, delta要减少几]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean decr(String key, long delta){
        try {
            if (delta<0){
                return false;
            }
            redisTemplate.opsForValue().increment(key,-delta);
            return true;
        }catch (Exception e) {
            return false;
        }
    }

    /**
     * @Description:  获取hash的某个键的值
     * @Param: [key 键, item:hash里的键]
     * @return:
     * @Author: 赖湧斌
     * @Date: 2020-06-17
    com.laiYongBin.util.RedisTempUtil
     */
    public Object hget(String key, String item){
        try{
            return redisTemplate.opsForHash().get(key,item);
        }catch (Exception e){
            return null;
        }
    }

    /**
     * @Description: 向Hash中添加数据,如果hash不存在则创建
     * @Param: [key, item, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean hset(String key, String item,Object value){
        try {
            redisTemplate.opsForHash().put(key,item,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 向Hash中添加数据,如果hash不存在则创建,并设置过期时间
     * @Param: [key, item, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean hset(String key, String item,Object value,long time){
        try {
            redisTemplate.opsForHash().put(key,item,value);
            if (time>0){
                expire(key,time);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }


    /**
     * @Description: 获取hash的所有键的值
     * @Param: [key]

    com.laiYongBin.util.RedisTempUtil
     */
    public Map<Object, Object> hmget(String key){
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * @Description: 存入多个键值对到一个Hash里
     * @Param: [key, map]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean hmset(String key,Map < Object,Object> map){
        try {
            redisTemplate.opsForHash().putAll(key,map);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 存入多个键值对到一个Hash里,并设置过期时间,若果时间小于0,则不设置
     * @Param: [key, map]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean hmset(String key,Map < Object,Object> map,long time){
        try {
            redisTemplate.opsForHash().putAll(key,map);
            if (time>0){
                expire(key,time);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description:删除hsh的值
     * @Param: [key不能为空, item不能为空]
    com.laiYongBin.util.RedisTempUtil
     */
    public void hdel(String key, Object... item){
        redisTemplate.opsForHash().delete(key,item);
    }

    /**
     * @Description: 判断是否含有key
     * @Param: [key, item]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean hHasKey(String key, String item){
        return redisTemplate.opsForHash().hasKey(key,item);
    }

    /**
     * @Description: Hash递增,如果不存在就会创建一个,并把新增的值返回
     * @Param: [key, item, by]
    com.laiYongBin.util.RedisTempUtil
     */
    public double hincr(String key,String item,double by){
        return redisTemplate.opsForHash().increment(key,item,by);
    }

    /**
     * @Description: Hash递减,如果不存在就会创建一个,并把新增的值返回
     * @Param: [key, item, by]
    com.laiYongBin.util.RedisTempUtil
     */
    public double hdecr(String key,String item,double by){
        return redisTemplate.opsForHash().increment(key,item,-by);
    }

    /**
     * @Description: 获取set的所有值
     * @Param: [key]
    com.laiYongBin.util.RedisTempUtil
     */
    public Set<Object> sGet(String key){
        try {
            return redisTemplate.opsForSet().members(key);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @Description: 判断set中是否含有某个值
     * @Param: [key, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean sHasKey(String key,Object value){
        try{
            return redisTemplate.opsForSet().isMember(key,value);
        }catch (Exception e){
            return false;
        }
    }

    /**
     * @Description: set一个或多个值进入set集合中
     * @Param: [key, values...]

    com.laiYongBin.util.RedisTempUtil
     */
    public long sSet(String key, Object... values){
        try {
            return redisTemplate.opsForSet().add(key,values);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * @Description: set一个或多个值进入set集合中,设置过期时间
     * @Param: [key, values...]

    com.laiYongBin.util.RedisTempUtil
     */
    public long sSet(String key,long time, Object... values){
        try {
            Long add = redisTemplate.opsForSet().add(key, values);
            if (time>0){
                expire(key,time);
            }
            return add;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * @Description: 获取set的长度
     * @Param: [key]
    com.laiYongBin.util.RedisTempUtil
     */
    public long sGetSetSize(String key){
        try{
            return redisTemplate.opsForSet().size(key);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * @Description: 移除一个或多个set里的值
     * @Param: [key, values...]
    com.laiYongBin.util.RedisTempUtil
     */
    public long setRemove(String key, Object... values){
        try {
            return redisTemplate.opsForSet().remove(key,values);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * @Description: 获取list的长度
     * @Param: [key]
    com.laiYongBin.util.RedisTempUtil
     */
    public long lGetListSize(String key){
        try{
            return redisTemplate.opsForList().size(key);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * @Description: 通过索引获取list的值
     * @Param: [key, index]
    com.laiYongBin.util.RedisTempUtil
     */
    public Object lGetIndex(String key,long index){
        try {
            return redisTemplate.opsForList().index(key,index);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @Description: 将值放入list
     * @Param: [key, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean lSet(String key, Object value){
        try {
            redisTemplate.opsForList().rightPush(key,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 将值放入list,设置过期时间
     * @Param: [key, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean lSet(String key, Object value,long time){
        try {
            redisTemplate.opsForList().rightPush(key,value);
            if (time>0){
                expire(key,time);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 将List放入list中
     * @Param: [key, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean lSet(String key, List<Object> value){
        try {
            redisTemplate.opsForList().rightPushAll(key,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 将List放入list中,设置过期时间
     * @Param: [key, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean lSet(String key, List<Object> value,long time){
        try {
            redisTemplate.opsForList().rightPushAll(key,value);
            if (time>0){
                expire(key,time);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description: 根据索引修改值
     * @Param: [key, index, value]
    com.laiYongBin.util.RedisTempUtil
     */
    public boolean lUpdateByIndex(String key,long index,Object value){
        try {
            redisTemplate.opsForList().set(key,index,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    public long lRemove(String key,long count,Object value){
        try {
            return redisTemplate.opsForList().remove(key,count,value);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }
}
